﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.OleDb;
using System.Configuration;
using System.Data;
using System.Collections;


class CConexion : IConexion
{
    #region Propiedades publicas y privadas
    protected OleDbConnection _cn = new OleDbConnection();
    protected OleDbCommand _cmd = new OleDbCommand();
    protected OleDbDataAdapter _da = new OleDbDataAdapter();
    protected string _cadenaConexion;
    protected DataSet _ds = new DataSet();
    protected OleDbTransaction _ole_transac;
    
    #endregion

    public CConexion()
    {
        _cadenaConexion = ConfigurationManager.ConnectionStrings["ESMOffline.Properties.Settings.ESMConnectionString"].ToString();
        _cmd.Connection = _cn;
        
    }


    /// <summary>
    /// Metodos de conexion
    /// </summary>
    /// <returns></returns>
    /// 
    #region Miembros de IConexion


    #region Metodos de Conexion


    public string Conectar()
    {
        try
        {
            if (!string.IsNullOrEmpty(_cadenaConexion))
            {
                _cn.ConnectionString = _cadenaConexion;

                if (_cn.State == System.Data.ConnectionState.Closed)
                {
                    _cn.Open();
                }
                else
                {
                    return "el estado de la conexion es abierto por tanto no se puede completar la operacion.";
                }

            }


            return "La operacion a terminado con exito";
        }
        catch (OleDbException ex_OleDb)
        {

            return "Operacion fallida (OleDbExeption): " + ex_OleDb;
        }
        catch (Exception ex)
        {

            return "Operacion fallida (Exception): " + ex;
        }




    }

    public string Desconectar()
    {
        try
        {
            if (!string.IsNullOrEmpty(_cadenaConexion))
            {
                _cn.ConnectionString = _cadenaConexion;

                if (_cn.State == System.Data.ConnectionState.Open)
                {
                    _cn.Close();
                }
                else
                {
                    return "el estado de la conexion es Cerrada por tanto no se puede completar la operacion.";
                }

            }


            return "La operacion a terminado con exito";
        }
        catch (OleDbException ex_OleDb)
        {

            return "Operacion fallida (OleDbExeption): " + ex_OleDb;
        }
        catch (Exception ex)
        {

            return "Operacion fallida (Exception): " + ex;
        }

    }

    #endregion
    /// <summary>
    /// Retorna un conjunto de datos almacenados en DataSet
    /// </summary>
    /// <param name="NombreDataSet"></param>
    /// <param name="NombreTabla"></param>
    /// <param name="NombreProcedimiento"></param>
    /// <param name="NombreParametros"></param>
    /// <param name="ValorParametros"></param>
    /// <param name="TiposDato"></param>
    /// <returns></returns>
    #region Cargar Datos
    public System.Data.DataSet Cargar_Datos(string NombreDataSet, string NombreTabla, string NombreProcedimiento, System.Collections.ArrayList NombreParametros, System.Collections.ArrayList ValorParametros, System.Collections.ArrayList TiposDato)
    {
        try
        {
            //Eliminamos todas las tablas de la base de datos para cargar datos en el DataSet vacio...
            _ds.Tables.Clear();
            //Asignamos el OleDbcommand a nuestro OleDbDataAdapter...
            _da.SelectCommand = _cmd;
            //Creamos una tabla donde devolveremos los datos requeridos con su nombre respectivo...
            _ds.Tables.Add(NombreTabla);
            //Procedemos a eliminar los parametros de nuestro OleDbcommand para que no nos genere datos repetidos con parametros anteriores...
            _da.SelectCommand.Parameters.Clear();
            //Creamos un ciclo para agregar cada uno de los parametros a nuestro OleDbcommand...
            for (int i = 0; i < NombreParametros.Count; i++)
            {
                _da.SelectCommand.Parameters.Add(NombreParametros[i].ToString(), (OleDbType)TiposDato[i]).Value = ValorParametros[i];
            }
            //verificamos que la conexion este abierta para ejecutar la informacion recopilada...
            if (_cn.State == ConnectionState.Open)
            {
                //Ejecutamos la informacion recopilada...
                _ole_transac.Begin();
                _da.SelectCommand.ExecuteNonQuery();
                _ole_transac.Commit();
                //Cargamos los datos en el Dataset creado anteriormente...
                _da.Fill(_ds.Tables[NombreTabla]);
            }

            return _ds;
        }
        catch (OleDbException)
        {
            _ole_transac.Rollback();
            return _ds;
        }
        catch (Exception)
        {
            return _ds;
        }
    }

    public System.Data.DataSet Cargar_Datos(string NombreDataSet, ArrayList NombreTabla, System.Collections.ArrayList Nombres_Procedimiento, System.Collections.ArrayList NombreParametros, System.Collections.ArrayList ValorParametros, System.Collections.ArrayList TiposDato)
    {
        try
        {
            //Eliminamos todas las tablas de la base de datos para cargar datos en el DataSet vacio...
            _ds.Tables.Clear();
            //Asignamos el OleDbcommand a nuestro OleDbDataAdapter...
            _da.SelectCommand = _cmd;
            //Predifinos el tipo de text en este caso es un procedimiento almacenado
            _da.SelectCommand.CommandType = CommandType.StoredProcedure;
            //Creamos un ciclo que nos permitira cargar datos en varias tablas
            for (int n = 0; n < Nombres_Procedimiento.Count; n++)
            {
                //Asignamos el nombre de procedimiento a el commandtext
                _da.SelectCommand.CommandText = Nombres_Procedimiento[n].ToString();

                //Creamos una tabla donde devolveremos los datos requeridos con su nombre respectivo...
                _ds.Tables.Add(NombreTabla[n].ToString());
                //Procedemos a eliminar los parametros de nuestro OleDbcommand para que no nos genere datos repetidos con parametros anteriores...
                _da.SelectCommand.Parameters.Clear();
                //Creamos un ciclo para agregar cada uno de los parametros a nuestro OleDbcommand...
                for (int i = 0; i < NombreParametros.Count; i++)
                {
                    _da.SelectCommand.Parameters.Add(NombreParametros[i].ToString(), (OleDbType)TiposDato[i]).Value = ValorParametros[i];
                }
                //verificamos que la conexion este abierta para ejecutar la informacion recopilada...
                if (_cn.State == ConnectionState.Open)
                {
                    //Ejecutamos la informacion recopilada...
                    _ole_transac.Begin();
                    _da.SelectCommand.ExecuteNonQuery();
                    _ole_transac.Commit();
                    //Cargamos los datos en el Dataset creado anteriormente...
                    _da.Fill(_ds.Tables[NombreTabla[n].ToString()]);
                }
            }

            return _ds;
        }
        catch (OleDbException)
        {
            _ole_transac.Rollback();
            return _ds;
        }
        catch (Exception) { return _ds; }
    }

    #endregion
    public ArrayList Ejecutar(string Query)
    {
        try
        {
            //_cmd.Transaction = _cn.BeginTransaction();

            //Eliminamos los parametros de nuestro OleDbcommand para no generar datos repetidos
            _cmd.Parameters.Clear();
            //Identificamos el metodo de ejecucion en este caso se utiliza un procedimiento almacenado
            _cmd.CommandType = CommandType.Text;

            //Asignamos el nombre de procedimiento almacenado a nuestro commandtext
            _cmd.CommandText = Query;

            //verificamos el estado de conexion para ejcutar la informacion recopilada
            if (_cn.State == ConnectionState.Open)
            {
                //ejecutamos la informacion recopilada
                var data_return = _cmd.ExecuteReader();

                int cant_items = data_return.FieldCount;

                ArrayList valores_a_retornar = new ArrayList();

                //si hay filas afectadas retornamos un valor verdadero
                while (data_return.Read())
                {
                    for (int i = 0; i < cant_items; i++)
                    {
                        valores_a_retornar.Add(data_return[i]);
                    }
                }
                data_return.Close();

                return valores_a_retornar;
            }
            //si el stado de la conxion es cerrado no se procede a ejecutar el procedimiento
            else
            {
                return null;
            }
        }
        //Devuelve un error especifico de OleDb
        catch (OleDbException) { return null; }

        //Devuelve un error general de la aplicacion
        catch (Exception) { return null; }

    }

    public bool Insertar(string procedimiento_query, System.Collections.ArrayList NombreParametros, System.Collections.ArrayList ValorParametros, System.Collections.ArrayList TiposDato, bool esQuery = false)
    {
        try
        {
            //_cmd.Transaction = _cn.BeginTransaction();

            //Eliminamos los parametros de nuestro OleDbcommand para no generar datos repetidos
            _cmd.Parameters.Clear();
            //Identificamos el metodo de ejecucion en este caso se utiliza un procedimiento almacenado
            if (esQuery)
                _cmd.CommandType = CommandType.Text;
            else
                _cmd.CommandType = CommandType.StoredProcedure;
            //Asignamos el nombre de procedimiento almacenado a nuestro commandtext
            _cmd.CommandText = procedimiento_query;

            //Creamos un for para agregar parametros a nuestro OleDbcommand vacio
            for (int i = 0; i < NombreParametros.Count; i++)
            {
                _cmd.Parameters.Add(NombreParametros[i].ToString(), (OleDbType)TiposDato[i]).Value = ValorParametros[i];
            }
            //verificamos el estado de conexion para ejcutar la informacion recopilada
            if (_cn.State == ConnectionState.Open)
            {
                //ejecutamos la informacion recopilada
                int Filas_Afectadas = _cmd.ExecuteNonQuery();

                //si hay filas afectadas retornamos un valor verdadero
                if (Filas_Afectadas != 0)
                    return true;
                // sino el valor sera false
                else
                    return false;
            }
            //si el stado de la conxion es cerrado no se procede a ejecutar el procedimiento
            else
            {
                return false;
            }
        }
        //Devuelve un error especifico de OleDb
        catch (OleDbException)
        {
            return false;
        }
        //Devuelve un error general de la aplicacion
        catch (Exception) { return false; }

    }

    public bool Insertar(System.Collections.ArrayList NombreProcedimientos, System.Collections.ArrayList NombreParametros, System.Collections.ArrayList ValorParametros, System.Collections.ArrayList TiposDato)
    {
        try
        {
            int Filas_Afectadas;
            //Identificamos el metodo de ejecucion en este caso se utiliza un procedimiento almacenado
            _cmd.CommandType = CommandType.StoredProcedure;

            for (int j = 0; j < NombreProcedimientos.Count; j++)
            {
                //Eliminamos los parametros de nuestro OleDbcommand para no generar datos repetidos
                _cmd.Parameters.Clear();

                //Asignamos el nombre de procedimiento almacenado a nuestro commandtext
                _cmd.CommandText = NombreProcedimientos[j].ToString();

                //Creamos un for para agregar parametros a nuestro OleDbcommand vacio
                for (int i = 0; i < NombreParametros.Count; i++)
                {
                    _cmd.Parameters.Add(NombreParametros[i].ToString(), (OleDbType)TiposDato[i]).Value = ValorParametros[i];
                }

                //verificamos el estado de conexion para ejcutar la informacion recopilada
                if (_cn.State == ConnectionState.Open)
                {
                    _ole_transac.Begin();
                    //ejecutamos la informacion recopilada
                    Filas_Afectadas = _cmd.ExecuteNonQuery();
                    _ole_transac.Commit();

                    //si hay filas afectadas retornamos un valor verdadero
                    if (Filas_Afectadas != 0)
                        return false;

                    // sino el valor sera false
                    else
                        return false;
                }
                //si el estado de la conxion es cerrado no se procede a ejecutar el procedimiento
                else
                {
                    return false;
                }

            }

            return true;
        }

        //Devuelve un error especifico de OleDb
        catch (OleDbException)
        {
            _ole_transac.Rollback();
            return false;
        }

        //Devuelve un error general de la aplicacion
        catch (Exception)
        {
            return false;
        }

    }

    public bool Eliminar(string Consulta, System.Collections.ArrayList NombreParametros, System.Collections.ArrayList ValorParametros, System.Collections.ArrayList TiposDato)
    {
        throw new NotImplementedException();
    }

    public bool Eliminar(System.Collections.ArrayList Consulta, System.Collections.ArrayList NombreParametros, System.Collections.ArrayList ValorParametros, System.Collections.ArrayList TiposDato)
    {
        throw new NotImplementedException();
    }

    public bool Editar()
    {
        throw new NotImplementedException();
    }

    #endregion
}
